/*
 * list.c
 *
 *  Created on: 2011-11-23
 *      Author: xugp
 */

#include <string.h>
#ifdef   DMALLOC
#include <dmalloc.h>
#else
#include <stdlib.h>
#endif
#include "list.h"
#ifndef __USE_ISOC99
#define inline
#endif



list_t * list_create(){
	list_t * plist=malloc(sizeof(list_t));
	memset(plist,0,sizeof(list_t));

	return plist;
}

void list_free(list_t * plist){
	node_t *t;
	if(NULL!=plist){
		while(plist->head){
			t=plist->head;
			plist->head=t->next;
			free(t);
		}
	}
}


node_t * list_push_head(void * data,list_t * plist){
	node_t * node=malloc(sizeof(node_t));
	node->data=data;
	node->pre=NULL;
	node->next=NULL;
	if(plist->head==NULL){
		plist->head=node;
		plist->count++;
	}else{
		node->next=plist->head;
		plist->head->pre=node;
		plist->head=node;
		plist->count++;
	}

	if(plist->tail==NULL){
		plist->tail=node;
	}
	return node;
}

node_t * list_push_tail(void * data,list_t * plist){
	node_t * node=malloc(sizeof(node_t));
	node->data=data;
	node->pre=NULL;
	node->next=NULL;
	if(plist->tail==NULL){
		plist->tail=node;
		plist->count++;
	}else{
		node->pre=plist->tail;
		plist->tail->next=node;
		plist->tail=node;
		plist->count++;
	}
	if(plist->head==NULL){
		plist->head=node;
	}
	return node;
}

node_t * list_delete(node_t *node,list_t * plist){
	node_t * result=NULL;

	if(node->pre!=NULL){
		node->pre->next=node->next;
	}
	if(node->next!=NULL){
		node->next->pre=node->pre;
	}

	result=node->next;

	if(node==plist->head){
		plist->head=node->next;
	}
	if(node==plist->tail){
		plist->tail=node->pre;
	}

	plist->count--;
	free(node);

	return result;
}

void * list_pop_head(list_t *plist){
	void *t=NULL;
	if(plist->head!=NULL){
		t= plist->head->data;
		list_delete(plist->head,plist);
	}
	return t;
}

void * list_pop_tail(list_t *plist){
	void *t=NULL;
	if(plist->tail!=NULL){
		t= plist->tail->data;
		list_delete(plist->tail,plist);
	}
	return t;
}

void list_remove(void * data,list_t * plist){
	node_t * node=plist->head;
	while(node!=NULL){
		if(node->data==data){
			list_delete(node,plist);
			break;
		}else{
			node=node->next;
		}
	}
}

